Skip to content

feat(chartjs): implement residual-plot - #11591

Merged
MarkusNeusinger merged 6 commits into
mainfrom
implementation/residual-plot/chartjs
Sep 5, 2026
Merged

feat(chartjs): implement residual-plot#11591
MarkusNeusinger merged 6 commits into
mainfrom
implementation/residual-plot/chartjs

Conversation

@github-actions

@github-actions github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Implementation: residual-plot - javascript/chartjs

Implements the javascript/chartjs version of residual-plot.

File: plots/residual-plot/implementations/javascript/chartjs.js

Parent Issue: #2332


🤖 impl-generate workflow

@claude

claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

AI Review - Attempt 1/3

Image Description

Light render (plot-light.png): Warm off-white (#FAF8F1) background. Title "residual-plot · javascript · chartjs · anyplot.ai" in dark ink at top, followed by a legend row (Zero reference / Residuals / Outliers (>2σ)). Data is a scatter of ~220 green (#009E73) circular points spread over Fitted Value ($150k–$600k) vs Residual (−80 to +80), a solid black zero-reference line, two amber dashed ±2σ bands with a faint shaded interior, and ~11 red (#AE3030) triangular outlier points beyond the bands. All text (title, axis titles, tick labels, legend) is dark and clearly readable against the light background — no legibility failures observed.

Dark render (plot-dark.png): Warm near-black (#1A1A17) background. Same layout — title and legend text render in light ink/white, axis titles and tick labels in a lighter secondary tone, all clearly legible against the dark surface with no dark-on-dark issues. The zero-reference line correctly flips to a light/white stroke (theme-adaptive "ink" token) while the amber dashed bands stay the same amber. Data marker colors (brand green circles, matte-red triangles) are pixel-identical to the light render — confirmed only chrome flipped, not data colors.

Both renders pass the theme-readability checklist (5c): no missing/invisible text in either theme, backgrounds match the specified hex targets, brand green is visible in both.

Score: 86/100

Category Score Max
Visual Quality 27 30
Design Excellence 13 20
Spec Compliance 15 15
Data Quality 14 15
Code Quality 10 10
Library Mastery 7 10
Total 86 100

Visual Quality (27/30)

  • VQ-01: Text Legibility (7/8) - All text readable in both themes at appropriate sizes; slightly conservative sizing leaves headroom
  • VQ-02: No Overlap (5/6) - A few marker clusters (e.g. near fitted≈250, fitted≈560) touch/overlap slightly
  • VQ-03: Element Visibility (5/6) - Marker size reasonable for n=220, but spec calls out alpha for overlapping points and none is used
  • VQ-04: Color Accessibility (2/2) - Outliers use both color (matte red) AND shape (triangle) — CVD-safe redundant encoding
  • VQ-05: Layout & Canvas (4/4) - Clean proportions, nothing clipped, no canvas-gate failure
  • VQ-06: Axis Labels & Title (2/2) - Descriptive axis titles with units ("Fitted Value ($1,000s)", "Residual ($1,000s)")
  • VQ-07: Palette Compliance (2/2) - First series brand green palette[0], outliers use semantic-red palette[4], amber anchor for threshold bands, correct theme backgrounds, identical data colors across themes

Design Excellence (13/20)

  • DE-01: Aesthetic Sophistication (5/8) - Thoughtful touches (relative-fill band, filtered legend) but overall a fairly standard scatter composition
  • DE-02: Visual Refinement (4/6) - L-shaped axis borders, subtle grid; nothing egregious but no standout refinement
  • DE-03: Data Storytelling (4/6) - Outlier highlighting and shaded ±2σ band create a clear focal hierarchy

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) - Correct residual (scatter) plot
  • SC-02: Required Features (4/4) - Zero-reference line ✓, ±2σ bands ✓, outlier color-coding ✓ (LOWESS smoothing and alpha are explicitly optional/advisory in the spec)
  • SC-03: Data Mapping (3/3) - X = fitted value, Y = residual (y_true − y_pred), full data range shown
  • SC-04: Title & Legend (3/3) - Title matches {spec-id} · {language} · {library} · anyplot.ai; legend labels are clear and correctly filtered to avoid duplicate band entries

Data Quality (14/15)

  • DQ-01: Feature Coverage (5/6) - Covers all required spec features; missing the advisory alpha treatment for overlapping points
  • DQ-02: Realistic Context (5/5) - Plausible house-price regression scenario (fitted $150k–$600k) with realistic heteroscedastic noise
  • DQ-03: Appropriate Scale (4/4) - Sensible value ranges for the domain

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) - Flat script; the two tiny RNG helper functions (lcg, gaussian) are the library-recommended deterministic-RNG pattern for browser code, not unnecessary abstraction
  • CQ-02: Reproducibility (2/2) - Fixed-seed LCG, fully deterministic
  • CQ-03: Clean Imports (2/2) - No stray imports; Chart global used directly
  • CQ-04: Code Elegance (2/2) - Appropriate complexity, no fake UI/interactivity
  • CQ-05: Output & API (1/1) - Correct mount-node contract, animation: false set, current Chart.js scatter/fill API

Library Mastery (7/10)

  • LM-01: Idiomatic Usage (4/5) - Good use of mixed scatter+line datasets and Chart.js's recommended patterns
  • LM-02: Distinctive Features (3/5) - Uses Chart.js's relative dataset fill: "+2" index technique and a legend filter callback to suppress duplicate band entries — beyond generic usage

Score Caps Applied

  • None

Strengths

  • Correct semantic palette use: brand green for the main residual series, palette[4] matte red and a triangle marker shape for outliers (redundant, CVD-safe encoding)
  • ±2σ threshold bands implemented via Chart.js's relative fill: "+2" index trick, with the legend filter callback cleanly hiding the two band traces so only meaningful entries show
  • Deterministic LCG-seeded data with realistic heteroscedastic noise (variance grows with fitted value) — a textbook regression-diagnostics pattern
  • Theme-adaptive chrome (zero-reference line, axis borders, tick/text colors) consistently sourced from ANYPLOT_TOKENS in both themes

Weaknesses

  • No alpha transparency on the residual markers despite the spec's guidance to "use alpha transparency for overlapping points" — a few clusters (near fitted≈250, fitted≈560) have touching/overlapping circles that would read cleaner with slightly reduced opacity or radius
  • No optional LOWESS/kernel smoothing trend line — would add diagnostic value for detecting non-linearity, though this is explicitly optional in the spec
  • Visual refinement is solid but generic — no standout design flourish beyond the functional band/outlier treatment

Issues Found

  1. VQ-03 / DQ-01 LOW: Overlapping residual markers with no alpha adjustment
    • Fix: Add backgroundColor with alpha (e.g. rgba at ~0.8) on the "Residuals" dataset, or slightly reduce pointRadius, to reduce visual clutter in dense clusters
  2. DE-01/DE-03 LOW: Composition is functional but not distinctive
    • Fix: Consider an optional LOWESS/rolling-mean trend line overlay to add diagnostic storytelling value, per the spec's optional suggestion

AI Feedback for Next Attempt

Solid, spec-compliant implementation. For further polish: add alpha transparency (or reduce point radius) on the residual scatter to handle overlapping clusters as the spec suggests, and consider adding an optional smoothing trend line to surface non-linearity patterns. Everything else — palette usage, theme adaptivity, band/outlier treatment — is working well and should be kept as-is.

Verdict: APPROVED

@github-actions github-actions Bot added quality:86 Quality score 86/100 ai-rejected Quality not OK, triggers update labels Sep 5, 2026
@github-actions github-actions Bot added ai-attempt-1 First repair attempt and removed ai-rejected Quality not OK, triggers update labels Sep 5, 2026
Attempt 1/4 - fixes based on AI review
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

🔧 Repair Attempt 1/4

Applied fixes based on AI review feedback.

Status: Repair completed, re-triggering review...


🤖 impl-repair

@claude

claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

AI Review - Attempt 2/3

Image Description

Light render (plot-light.png): Warm off-white (#FAF8F1) background. Title "residual-plot · javascript · chartjs · anyplot.ai" in dark ink, comfortably sized. Legend row below (Zero reference / Residuals / Smoothed trend / Outliers (>2σ)) in dark text. Axis titles "Fitted Value ($1,000s)" and "Residual ($1,000s)" with units, tick labels in softer dark grey, subtle light grid lines. Data: ~220 green (#009E73) residual points at ~0.7 alpha over Fitted Value ($150k–$600k) vs Residual (−80 to +80), a solid black zero-reference line, two amber dashed ±2σ lines with a faint shaded band, a light-purple dotted rolling-mean trend line, and ~11 matte-red triangular outliers beyond the bands. All text is clearly readable against the light background — no legibility failures.

Dark render (plot-dark.png): Warm near-black (#1A1A17) background. Same layout, now in light/white ink — title, legend, axis titles, and tick labels are all clearly legible against the dark surface with no dark-on-dark issues. The zero-reference line correctly flips to a light stroke (theme-adaptive ink token). Data marker colors (green points, amber bands, purple trend line, red triangles) are pixel-identical to the light render — confirms only chrome flipped, not data colors.

Both renders pass the theme-readability checklist: no missing/invisible text in either theme, backgrounds match the specified hex targets, brand green is visible in both.

Score: 94/100

Category Score Max
Visual Quality 29 30
Design Excellence 16 20
Spec Compliance 15 15
Data Quality 15 15
Code Quality 10 10
Library Mastery 9 10
Total 94 100

Visual Quality (29/30)

  • VQ-01: Text Legibility (8/8) - All text readable at appropriate sizes in both themes
  • VQ-02: No Overlap (5/6) - Alpha softens clusters but a few points near fitted≈250/≈560 still touch slightly
  • VQ-03: Element Visibility (6/6) - Alpha=0.7 now applied, addressing the attempt-1 finding
  • VQ-04: Color Accessibility (2/2) - Outliers use color AND triangle shape — CVD-safe redundant encoding
  • VQ-05: Layout & Canvas (4/4) - Clean proportions, nothing clipped
  • VQ-06: Axis Labels & Title (2/2) - Descriptive axis titles with units
  • VQ-07: Palette Compliance (2/2) - Brand green first series, semantic red for outliers, amber anchor for threshold, correct theme backgrounds

Design Excellence (16/20)

  • DE-01: Aesthetic Sophistication (7/8) - Theme-adaptive band shading, semantic colors, relative-fill technique, new trend line
  • DE-02: Visual Refinement (4/6) - Subtle grid, L-shaped axis borders, alpha blending; solid but not standout
  • DE-03: Data Storytelling (5/6) - Outlier highlighting + shaded band + new smoothed trend line create a clear diagnostic hierarchy

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) - Correct residual scatter plot
  • SC-02: Required Features (4/4) - Zero-reference line, ±2σ bands, outlier coloring, alpha, and smoothing trend all present
  • SC-03: Data Mapping (3/3) - X = fitted value, Y = residual, full range shown
  • SC-04: Title & Legend (3/3) - Title matches mandated format, legend clearly deduplicated

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) - Now covers all spec features, including the two previously-missing optional ones
  • DQ-02: Realistic Context (5/5) - Plausible house-price regression scenario with realistic heteroscedastic noise
  • DQ-03: Appropriate Scale (4/4) - Sensible value ranges for the domain

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) - Flat script; RNG/rgba helpers are appropriate
  • CQ-02: Reproducibility (2/2) - Fixed-seed LCG, fully deterministic
  • CQ-03: Clean Imports (2/2) - No stray imports
  • CQ-04: Code Elegance (2/2) - Appropriate complexity, no fake UI
  • CQ-05: Output & API (1/1) - Correct mount-node contract, animation: false, current API

Library Mastery (9/10)

  • LM-01: Idiomatic Usage (4/5) - Good use of mixed scatter+line datasets
  • LM-02: Distinctive Features (5/5) - Relative fill: "+2" trick, theme-adaptive band tint, legend.filter callback, and rolling-window trend computation

Score Caps Applied

  • None

Strengths

  • Addressed both attempt-1 weaknesses directly: added alpha transparency (rgba palette[0] at 0.7) on residual markers, and added a rolling-mean smoothed trend line to surface non-linear patterns
  • Correct semantic palette usage: brand green for residuals, matte-red AND triangle shape for outliers (redundant, CVD-safe), amber anchor for ±2σ threshold lines
  • Theme-adaptive ±2σ band shading: the relative-fill overlay tint flips (dark tint on light bg, light tint on dark bg) so the shaded region stays subtly visible in both themes
  • Deterministic LCG + Box-Muller-style gaussian data with realistic heteroscedastic house-price regression scenario
  • Idiomatic Chart.js technique mix: relative fill: "+2" index trick, legend.filter callback to suppress duplicate band entries

Weaknesses

  • A few marker clusters (e.g. near fitted≈250, fitted≈560) still touch slightly even with alpha=0.7 — a marginally lower alpha or smaller point radius in dense regions would separate them further
  • The two ±2σ threshold lines are filtered out of the legend entirely rather than merged into one labeled entry — a first-time viewer has no textual cue for what the dashed amber lines represent
  • Visual refinement is professional but not distinctive beyond the functional band/outlier/trend treatments

Issues Found

  1. VQ-02 LOW: A few residual marker clusters still touch slightly despite alpha=0.7
    • Fix: Reduce pointRadius marginally (e.g. 6 → 5) or lower alpha slightly further (e.g. 0.6) in the densest regions
  2. SC-04 LOW: ±2σ band lines have no legend entry at all
    • Fix: Merge the two band datasets into a single labeled "±2σ band" legend entry instead of filtering both out

AI Feedback for Next Attempt

Strong implementation — both attempt-1 weaknesses (missing alpha, missing trend line) are now resolved with thoughtful, theme-adaptive execution. Remaining polish is minor: consider a single merged "±2σ band" legend entry instead of hiding both band traces, and a touch more separation (radius or alpha) in the densest marker clusters. Everything else — palette usage, theme adaptivity, band/outlier/trend treatment — is working well and should be kept as-is.

Verdict: APPROVED

@github-actions github-actions Bot added quality:94 Quality score 94/100 ai-approved Quality OK, ready for merge and removed quality:86 Quality score 86/100 labels Sep 5, 2026
@MarkusNeusinger
MarkusNeusinger merged commit fa41112 into main Sep 5, 2026
@MarkusNeusinger
MarkusNeusinger deleted the implementation/residual-plot/chartjs branch September 5, 2026 12:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-approved Quality OK, ready for merge ai-attempt-1 First repair attempt quality:94 Quality score 94/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant